from fdfs_client.client import Fdfs_client
from django.core.files.storage import Storage
from django.conf import settings


class FastDFSStorage(Storage):
    """自定义文件存储系统类"""
    def __init__(self, client_conf=None, base_url=None):
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.base_url = base_url or settings.FDFS_BASE_URL

    def _open(self, name, mode='rb'):
        """
        打开文件，实现文件存储到远端FastDFS不需要打开文件
        :param name: 需要打开的文件名
        :param mode: 打开文件模式 read bytes
        :return:
        """
        pass

    def _save(self, name, content, max_length=None):
        """
        文件存储时调用此方法
        :param name: 需要上传的文件的文件名
        :param content:  以rb模式打开的文件对象，contend.read() 可以读取文件的二进制数据
        :param max_length:
        :return:  file_id
        """
        # 1创建FastDFS 客户端
        client = Fdfs_client(self.client_conf)
        # 2 调用上传文件的方法上传文件到FastDFS服务器
        ret = client.upload_by_buffer(content.read())
        # 3 判断是否上传成功
        if ret.get('Status') != 'Upload successed.':
            raise Exception('Upload failed')
        # 4 返回上传成功后得到file_id
        return ret.get('Remote file_id')

    def exists(self, name):
        """
        当要进行上传时都调用此方法判断文件是否已上传,如果没有上传才会调用save方法进行上传
        :param name: 要上传的文件名
        :return: True(表示文件已存在,不需要上传)  False(文件不存在,需要上传)
        """
        return False

    def url(self, name):
        """
        当要访问图片时,就会调用此方法获取图片文件的绝对路径
        :param name: 要访问图片的file_id
        :return: 完整的图片访问路径
        """
        return self.base_url + '/' + name
